﻿#include "statemachinedefinition.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QDebug>
#include <QTextDocumentFragment>

using namespace StateMachineDefine;

TransKind jsonValueToTransKind(QJsonValue value)
{
    if (value.isString()) {
        if(value.toString()=="0")
        {
            return STRONG;
        }

        if(value.toString()=="1")
        {
            return WEAK;
        }

        if(value.toString()=="2")
        {
            return SYNCHRO;
        }
    } else {
        switch (value.toInt()) {
        case 0:
            return STRONG;
        case 1:
            return WEAK;
        case 2:
            return SYNCHRO;
        }
    }
}

TransHistory jsonValueToTransHistory(QJsonValue value)
{
    if (value.isString()) {
        if(value.toString()=="0")
        {
            return RESTART;
        }

        if(value.toString()=="1")
        {
            return RESUME;
        }
    } else {
        switch (value.toInt()) {
        case 0:
            return RESTART;
        case 1:
            return RESUME;

        }
    }

}

static QJsonObject QRectToJsonObject(const QRect &rect) {
    QJsonObject obj;
    obj["x"] = rect.x();
    obj["y"] = rect.y();
    obj["width"] = rect.width();
    obj["height"] = rect.height();
    return obj;
}

static QRect QRectFromJsonObject(const QJsonObject &json) {
    return QRect(json["x"].toInt(), json["y"].toInt(), json["width"].toInt(), json["height"].toInt());
}


static QJsonArray VectorToJsonArray(const QVector<QString> & vec) {
    QJsonArray array;
    for (const QString &str : vec) {
        array.append(str);
    }
    return array;
}


static QVector<QString> JsonArrayToVector(const QJsonArray & array) {
    QVector<QString> vec;
    for (const QJsonValue val: array) {
        vec.append(val.toString());
    }
    return vec;
}

static QJsonObject QPointToJsonObject(const QPoint &point) {
    QJsonObject obj;
    obj["x"] = point.x();
    obj["y"] = point.y();
    return obj;
}

static QPoint QPointFromJsonObject(const QJsonObject &json) {
    return QPoint(json["x"].toInt(), json["y"].toInt());
}

QString Transition::condition() const
{
    return  QTextDocumentFragment::fromHtml(condition_).toPlainText();
}

void Transition::setCondition(const QString &condition)
{
    condition_ = condition.toHtmlEscaped();
}

QString Transition::actions() const
{
    return QTextDocumentFragment::fromHtml(actions_).toPlainText();
}

void Transition::setActions(const QString &actions)
{
    actions_ = actions.toHtmlEscaped();
}

QJsonObject Transition::toJson() const
{
    QJsonObject obj;
    obj["oid"] = oid;
    obj["comment"] = comment;
    obj["target"] = target;
    obj["source"] = source;
    obj["kind"] = static_cast<int>(kind);
    obj["history"] = static_cast<int>(history);
    obj["prior"] = static_cast<int>(prior);
    obj["isActive"] = isActive;

    QJsonObject geObj;

    QJsonArray pathArray;
    for (const QPoint &point : ge.path) {
        pathArray.append(QPointToJsonObject(point));
    }
    geObj["path"] = pathArray;
    geObj["present"]=ge.present;

    obj["ge"] = geObj;
    obj["condition"] = condition_;
    obj["action"] = actions_;

    return obj;
}

void Transition::fromJson(const QJsonObject & json)
{
    oid = json["oid"].toString();
    comment = json["comment"].toString();
    target = json["target"].toString();
    source = json["source"].toString();    
    kind = jsonValueToTransKind(json["kind"]);
    history = jsonValueToTransHistory(json["history"]);
    prior = json["prior"].toInt();
    isActive = json["isActive"].toBool();

    ge.path.clear();
    QJsonObject geObj = json["ge"].toObject();


    QJsonArray pathArray = geObj["path"].toArray();
    for (const QJsonValue pointValue : pathArray) {
        ge.path.append(QPointFromJsonObject(pointValue.toObject()));
    }
    ge.present=geObj["present"].toString();

    condition_ = json["condition"].toString();
    actions_ = json["action"].toString();
}

QJsonObject StateMachine::toJson() const
{
    QJsonObject obj;
    obj["oid"] = oid;
    obj["name"] = name;
    obj["comment"] = comment;
    obj["projectid"] = projectid;
    obj["poufilename"] = poufilename;
    obj["filename"] = filename;
    obj["projectpath"] = projectpath;
    obj["hierarchy"] = hierarchy;
    obj["initstate"] = initstate;
    obj["statelist"] = VectorToJsonArray(statelist);
    obj["parentType"] = parentType;
    obj["parentOid"] = parentOid;
    obj["operatorOid"] = operatorOid;
    obj["isSaved"] = isSaved;

    return obj;
}

void StateMachine::fromJson(const QJsonObject & json)
{
    oid = json["oid"].toString();
    name = json["name"].toString();
    comment = json["comment"].toString();
    filename = json["filename"].toString();
    projectpath = json["projectpath"].toString();
    hierarchy = json["hierarchy"].toString();
    projectid = json["projectid"].toString();
    poufilename = json["poufilename"].toString();
    initstate = json["initstate"].toString();
    statelist = JsonArrayToVector(json["statelist"].toArray());    
    parentType = json["parentType"].toString();
    parentOid = json["parentOid"].toString();
    operatorOid = json["operatorOid"].toString();
    isSaved = json["isSaved"].toBool();
}

QJsonObject State::toJson() const
{
    QJsonObject obj;
    obj["oid"] = oid;
    obj["name"] = name;
    obj["hierarchy"] = hierarchy;
    //obj["notes"] = notes;
    obj["comment"] = comment;
    obj["parentid"] = parentid;
    obj["initial"] = initial;
    obj["final"] = final;
    obj["isActive"] = isActive;

    // 序列化 QString 类型的 QVector
    obj["stmList"] = VectorToJsonArray(stmList);
    obj["trans_strong"] = VectorToJsonArray(trans_strong);
    obj["trans_weak"] = VectorToJsonArray(trans_weak);
    obj["trans_sync"] = VectorToJsonArray(trans_sync);

    // 序列化 pouList（每个元素都是一个 POU 结构体）
    QJsonArray pouArray;
    for (const POU &pou : pouList) {
        QJsonObject pouObj;
        pouObj["oid"] = pou.oid;
        pouObj["name"] = pou.name;
        pouObj["filePath"] = pou.filePath;
        pouArray.append(pouObj);
    }
    obj["pouList"] = pouArray;

    // 序列化状态的图形信息（StateGE）
    QJsonObject geObj;
    geObj["present"] = ge.present;
    geObj["rect"] = QRectToJsonObject(ge.rect);
    obj["ge"] = geObj;

    return obj;
}



void State::fromJson(const QJsonObject &json)
{
    oid = json["oid"].toString();
    name = json["name"].toString();
    hierarchy = json["hierarchy"].toString();
    //notes = json["notes"].toString();
    comment = json["comment"].toString();
    parentid = json["parentid"].toString();
    initial = json["initial"].toBool();
    final = json["final"].toBool();
    isActive = json["isActive"].toBool();

    // 反序列化 QString 类型的 QVector
    stmList = JsonArrayToVector(json["stmList"].toArray());
    trans_strong = JsonArrayToVector(json["trans_strong"].toArray());
    trans_weak = JsonArrayToVector(json["trans_weak"].toArray());
    trans_sync = JsonArrayToVector(json["trans_sync"].toArray());

    // 反序列化 pouList
    pouList.clear();
    QJsonArray pouArray = json["pouList"].toArray();
    for (int i = 0; i < pouArray.size(); ++i) {
        QJsonObject pouObj = pouArray.at(i).toObject();
        POU pou;
        pou.oid = pouObj["oid"].toString();
        pou.name = pouObj["name"].toString();
        pou.filePath = pouObj["filePath"].toString();
        pouList.append(pou);
    }

    // 反序列化状态的图形信息（StateGE）
    QJsonObject geObj = json["ge"].toObject();
    ge.present = geObj["present"].toString();
    ge.rect = QRectFromJsonObject(geObj["rect"].toObject());
}



QJsonObject Operator::toJson() const
{
    QJsonObject obj;
    obj["oid"] = oid;
    obj["name"] = name;
    obj["projectOid"] = projectOid;
    obj["path"] = path;
    obj["stmList"] = VectorToJsonArray(stmList);

    return obj;
}

void Operator::fromJson(const QJsonObject &json)
{
    oid = json["oid"].toString();
    name = json["name"].toString();
    projectOid = json["projectOid"].toString();
    path = json["path"].toString();
    stmList = JsonArrayToVector(json["stmList"].toArray());

}

QJsonObject Project::toJson() const
{
    QJsonObject obj;
    obj["oid"] = oid;
    obj["path"] = path;
    obj["operatorList"] = VectorToJsonArray(operatorList);

    return obj;

}

void Project::fromJson(const QJsonObject &json)
{
    oid = json["oid"].toString();
    path = json["path"].toString();
    operatorList = JsonArrayToVector(json["operatorList"].toArray());

}

QJsonObject POU::toJson() const
{
    QJsonObject obj;
    obj["oid"] = oid;
    obj["name"] = name;
    obj["filePath"] = filePath;

    return obj;
}

void POU::fromJson(const QJsonObject &json)
{
    oid = json["oid"].toString();
    name = json["name"].toString();
    filePath = json["filePath"].toString();
}
